Skip to main content

UDP Server

该驱动内置了一个 udp server 服务, 驱动启动后可以接收客户端发送的数据. 如果使用容器部署时, 需要将 udp 服务端口开放.

配置说明

以下内容为 udp-server 驱动的配置项

server:
port: 9606 # UDP 监听的端口, 默认 9606

脚本说明

脚本语言: JavasScript ECMAScript 5.1

驱动使用时要求提供 数据处理脚本 来处理接收和发送数据过程中的协议和数据格式问题.

在脚本的上下文中内置了 Buffer 包, 可用于处理接收或发送二进制数据.

除此之外, 还内置了 lodash, crypto-js, moment, xml-jsformulajs(Excel函数) 包.

注: 所有的脚本函数名必须为 handler

客户端对象

客户端对象, 可以获取当前数据包的来源信息(包括: IP和Port). 并且可以管理数据上下文对象.

remoteAddr(属性)

用于获取发送数据包的客户端信息. 例如: 192.168.100.123:53041

示例
/**
* 连接处理脚本, 当与服务端连接建立或断开时执行的操作
*
* @param {object} client 客户端对象
* @param {Buffer} data 接收到的数据包
*/
function handler(client, data) {
// 例如: 192.168.100.123:53041
const remoteAddr = client.remoteAddr;
}

ip(属性)

用于获取发送数据包的客户端的IP地址. 例如: 192.168.100.123

示例
/**
* 连接处理脚本, 当与服务端连接建立或断开时执行的操作
*
* @param {object} client 客户端对象
* @param {Buffer} data 接收到的数据包
*/
function handler(client, data) {
// 例如: 192.168.100.123
const ipAddr = client.ip;
}

port(属性)

用于获取发送数据包的客户端的端口. 例如: 53041

示例
/**
* 连接处理脚本, 当与服务端连接建立或断开时执行的操作
*
* @param {object} client 客户端对象
* @param {Buffer} data 接收到的数据包
*/
function handler(client, data) {
// 例如: 53041
const port = client.port;
}

getContext

用于获取数据上下文对象, 可以在数据上下文中存储数据. 数据上下文对象

注: 第一次调用的时候才会创建数据上下文

参数说明
参数名参数类型参数说明示例值
contextIdString上下文标识"myContext"
返回值

Object. 数据上下文对象

示例
function handler(client, data) {
// 获取一个标识为 myContext 的上下文
var myContext = client.getContext("myContext");

// 使用客户端 IP 地址作为标识
var context = client.getContext(client.getRemoteIp());
}

getDeviceContext

用于获取设备数据上下文对象, 使用设备标识作为上下文标识, 可以在上下文中存储数据. 数据上下文对象

getContext 不同的是, 当设备被删除后, 重启驱动时会自动清理被删除设备的上下文对象.

注: 第一次调用的时候才会创建数据上下文

参数说明
参数名参数类型参数说明示例值
deviceIdString设备标识"ST10001"
返回值

Object. 数据上下文对象

示例
function handler(client) {
// 获取设备 ST10001 的上下文
var context = client.getDeviceContext("ST10001");
}

removeContext

删除上下文对象

参数说明
参数名参数类型参数说明示例值
contextIdString上下文标识"myContext"
返回值

示例
function handler(client) {
// 删除标识为 myContext 的上下文
client.removeContext("myContext");

// 删除以客户端 IP 地址作为标识的上下文
client.removeContext(client.getRemoteIp());
}

removeDeviceContext

删除设备上下文对象

参数说明
参数名参数类型参数说明示例值
deviceIdString上下文标识"ST10001"
返回值

示例
function handler(client) {
// 删除设备 ST10001 的上下文
client.removeDeviceContext("ST10001");
}

getContextIds

获取全部上下文标识(不包含设备上下文)

参数说明

返回值

String[]

示例
function handler(client) {
// 创建两个上下文
const context1 = client.getContext("context1");
const context2 = client.getContext("context2");

// 获取全部上下文标识 ["context1", "context2"]
const contextIds = client.getContextIds();
}

getDeviceContextIds

获取全部设备上下文标识(只包含设备上下文)

参数说明

返回值

String[]

示例
function handler(client) {
// 创建两个设备上下文
const context1 = client.getDeviceContext("ST10001");
const context2 = client.getDeviceContext("ST10002");

// 获取全部设备上下文标识 ["ST10001", "ST10002"]
const contextIds = client.getDeviceContextIds();
}

数据上下文

数据上下文对象, 用来存储数据.

注: 可以根据需求创建多个上下文对象, 但是上下文对象以及上下文中的数据需要及时清理, 否则会造成 OOM 问题, 导致驱动程序崩溃.

put

用于向上下文中存储数据.

注: 存入的数据需要自行清理, 否则可能导致 OOM 等问题.

参数说明
参数名参数类型参数说明
keystring数据项的 key
valueany数据项的值
返回值

示例
function handler(client, request) {
// 获取或创建标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 向上下文中存储一个数值
context.put("number", 3.141);
// 向上下文中存储一个对象
context.put("object", {name: "张三", age: 18});

// 获取或创建设备 ST10001 的上下文
const deviceContext = client.getDeviceContext("ST10001");
// 向上下文中存储一个字符串
deviceContext.put("string", "this is a string");
// 向上下文中存储一个数值
deviceContext.put("number", 3.141);
// 向上下文中存储一个对象
deviceContext.put("object", {name: "张三", age: 18});
}

containsKey

判断上下文中是否存在指定的 key

参数说明
参数名参数类型参数说明
keystring数据项的 key
返回值

bool. true 表示 key 存在, false 表示 key 不存在

示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");

// 返回 true
context.containsKey("string");
// 返回 false
context.containsKey("string1");
}

get

从上下文中获取指定的 key 对应的数据. 如果 key 不存在则返回 undefined

参数说明
参数名参数类型参数说明
keystring数据项的 key
返回值

anyundefined. 返回 put 时写入的数据.

示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");

// 返回 "this is a string"
context.get("string");

// 返回 undefined
context.get("string1");
}

getAndRemove

从上下文中获取指定的 key 对应的数据并且在返回后 删除key. 如果 key 不存在则返回 undefined.

注: 该函数返回后, 再使用 getgetAndRemove 均返回 undefined.

参数说明
参数名参数类型参数说明
keystring数据项的 key
返回值

anyundefined. 返回 put 时写入的数据.

示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");

// 向上下文中存储一个字符串
context.put("string", "this is a string");

// 返回 "this is a string"
context.getAndRemove("string");

// 返回 undefined
context.get("string");

// 返回 undefined
context.getAndRemove("string");
}

remove

从上下文中删除指定的 key, 如果 key 不存在则不执行任何操作.

参数说明
参数名参数类型参数说明
keystring数据项的 key
返回值

示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 数据被删除
context.remove("string");
// 不执行任何操作
context.remove("string");
}

数据处理脚本

该脚本用于处理接收到的数据包, 根据协议和数据格式将数据包解析为平台定义的数据格式.

函数定义如下:

/**
* 数据处理脚本, 解析从客户端接收到的数据并转换为平台规定的数据格式
*
* @param {object} context 上下文对象
* @param {Buffer} buffer 接收到的数据包
* @return {Array} 解析出的采集数据信息
*/
function handler(context, buffer) {
// 数据包处理逻辑

// 返回结果必须为数组, 数组中每个元素为一个设备的实时数据信息
return [
{
"id": "d01", // 设备标识
"time": 1665999863637, // 数据采集时间(ms), unix 时间戳
"values": {"key1": "str", "key2": 123} // 数据点, key 为数据点的标识, value: 为数据点的值
}
];
}
参数说明
参数名参数类型参数说明
contextobject上下文对象
bufferBuffer客户端发送的数据包
返回值
参数名参数类型参数说明示例值
array[object]对象数组返回值[{"id":"d01","time":1665999863637,"values":{"temperature":17.5,"humidity":35.7}}]
id字符串资产编号或设备标识d01
time数值时间戳(ms)1664256913000
fields对象数据点信息{"temperature":17.5,"humidity":35.7}
key字符串数据点标识"temperature"
valueany数据点的值17.5
示例
function handler(target, buffer) {
// 以 json 格式为例, 例如: {"id":"d01","time":"2022-10-17 17:57:32","values":[{"name":"temperature","data":17.5},{"name":"humidity","data":35.7}]}
const jsonData = JSON.parse(buffer.toString());
const time = moment(jsonData.time, "YYYY-MM-DD HH:mm:ss");
const values = {};
for (let i = 0; i < jsonData.values.length; i++) {
const value = jsonData.values[i];
values[value.name] = value.data;
}

return [
{id: jsonData.id, values: values, time: time.valueOf()}
]
}